﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MdcService.Configuration;
using MdcService.Service;
using MdcService.Static;
using MdcService.Structure;
using StackExchange.Redis;

namespace MdcService.DataAccess
{
	public class RedisDataAccess<T> :IRealTimeDataAccess<T> where T:MachineValue, new()
	{
		private ConfigurationService _configManager;

		private IDatabase _db => Manager.GetDatabase();

		public RedisDataAccess(ConfigurationService configManager)
		{
			_configManager = configManager;
		}

		public IEnumerable<T> Data { get; set; }

		public void Insert(T value)
		{
			_db.StringSet(value.Id, Utilities.SerializeObject(value));
		}

		public Task<bool> InsertAsync(T value)
		{
			return _db.StringSetAsync(value.Id, Utilities.SerializeObject(value));
		}

		public void Insert(IEnumerable<T> values)
		{
			values.ForEach(Insert);
		}

	    List<T> IDataAccess<T>.Select(string command)
	    {
	        throw new NotImplementedException();
	    }

	
		public IEnumerable<T> Select(string command)
		{
			var l = new List<T>();
			var x = _db.StringGet(command);
			if (x.HasValue)
			{
				var t =Utilities.DeserializeJsonToObject<T>(x.ToString());
				l.Add(t);
			}
			return l;
		}

		public Task<IEnumerable<T>> SelectAsync(string command)
		{
			throw new NotImplementedException();
		}

		public void Update(IEnumerable<T> values)
		{
			Insert(values);
		}

	    public void Update(T value)
	    {
	        throw new NotImplementedException();
	    }

	    public Task<bool> UpdateAsync(IEnumerable<T> values)
		{
			throw new NotImplementedException();
		}

		public void Delete(IEnumerable<T> values)
		{
			values.ForEach(i=>_db.KeyDelete(i.Id.ToString()));
		}

	    public void Delete(T value)
	    {
	        throw new NotImplementedException();
	    }

	    public Task<bool> DeleteAsync(IEnumerable<T> values)
		{
			throw new NotImplementedException();
		}

		private  ConnectionMultiplexer _redis;
		private  object _locker = new object();
		public ConnectionMultiplexer Manager
		{
			get
			{
				if (_redis == null)
				{
					lock (_locker)
					{
						if (_redis != null) return _redis;

						_redis = GetManager();
						return _redis;
					}
				}
				return _redis;
			}
		}

		private ConnectionMultiplexer GetManager()
		{
			var connectionString = _configManager.Configuration.RealtimeDbConnectionString;
			return ConnectionMultiplexer.Connect(connectionString);
		}
	}
}
